package Netty.old.NIO.组件.NIOBuffer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * Scattering将数据写入到buffer时，可以采用buffer数组， 依次入[分散]
 * Gathering从(buffer读取数据时，可以采用buffer数组， 依次读
 *
 * Scattering 撒开,分散,将来自于一个Channel的数据分散到多个Buffer当中,
 *              一个满了就用下一个,可以实现数据的分门别类.
 *              这样就省去了解析的时间,比如一个消息有三个部分,
 *              第一部分是头信息,第二部分是协议信息,第三部分是消息体.
 *              可以吧这三个消息分别放到不同的Buffer当中
 *
 * //启动telnet客户端  控制面板-》程序-》启动或关闭Windows功能-》telnet客户端 勾选
 * //cmd
 * //telnet 127.0.0.1 端口号
 * //ctrl+]
 * //send 发送的信息
 *
 */
public class 分散和聚集 {
    public static void main(String[] args) throws IOException {
        缓存数组缓存();
    }

    private static void 缓存数组缓存() throws IOException {
        //使用ServerSocketChannel和SocketChannel网络
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);
        serverSocketChannel.socket().bind(inetSocketAddress);//绑定端口到Socket

        ByteBuffer[] byteBuffers = new ByteBuffer[2];//创建缓存
        byteBuffers[0] = ByteBuffer.allocate(5);
        byteBuffers[1] = ByteBuffer.allocate(3);
        int messageLength = 8;//假定从客户端接受8字节

        //等待客户端连接
        SocketChannel socketChannel = serverSocketChannel.accept();

        while (true) {
            int byteRead = 0;

            while (byteRead < messageLength && byteRead>=0) {//每八个  一组  当读完8个  才结束

                byteRead += socketChannel.read(byteBuffers);//累计读取的字节数
                System.out.println("读取的数量" + byteRead);
                //使用流打印
                Arrays.stream(byteBuffers).map(byteBuffer ->"position:"+
                                byteBuffer.position()+"limit:"+byteBuffer.limit())
                        .forEach(System.out::println);
            }
            //将buffer进行反转
            Arrays.stream(byteBuffers).forEach(ByteBuffer::flip);

            int byteWrite = 0;
            //将数据读出显示器
            while (byteWrite < messageLength){
                byteWrite+=socketChannel.write(byteBuffers);
            }
            //清空 byteBuffers
            Arrays.stream(byteBuffers).forEach(ByteBuffer::clear);

            System.out.println("byteRead="+byteRead
                    +"byteWrite="+byteWrite
                    +"messageLength:"+messageLength);
            System.out.println(byteBuffers[0]+byteBuffers[1].toString());
        }
    }
}
